package muyan.yootk.loadbalancer.rule;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.ribbon.NacosServer;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

// 如果要想进行规则的定义常见的做法是直接使用IRule接口完成
// 推荐的做法是使用IRule接口对应的抽象子类AbstractLoadBalancerRule
@Slf4j
public class NacosWeightRule extends AbstractLoadBalancerRule { // Nacos权重规则
    @Autowired
    private NacosDiscoveryProperties nacosDiscoveryProperties; // Nacos配置属性
    private IClientConfig clientConfig;
    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {
        this.clientConfig = clientConfig;
    }
    @Override
    public Server choose(Object key) { // 选择服务实例
        BaseLoadBalancer loadBalancer = (BaseLoadBalancer) super.getLoadBalancer(); // 获取负载均衡器
        String name = loadBalancer.getName(); // 调用微服务名称
        // 此时的场景就变为了原生项目的NacosClient组件进行处理的操作了
        NamingService namingService = this.nacosDiscoveryProperties.namingServiceInstance(); // 发现服务
        // 根据指定的服务名称以及分组名称获取服务的实例
        try {
            Instance instance = namingService.selectOneHealthyInstance(name, this.nacosDiscoveryProperties.getGroup());
            // 整个的代码是工作在SpringCloud之中的，所以需要将获取到的Instance对象实例转为Server对象实例
            return new NacosServer(instance); // NacosServer是Server子类
        } catch (NacosException e) {
            log.error("获取Nacos注册的微服务实例出错，异常为：" + e);
            return null;
        }
    }
}
